/*
 * This file is part of ddesktop: remote desktop system for iPad 
 *
 * Copyright (C) 2010 Kazuhiro Satoh
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. if not, see <http://www.gnu.org/licenses/>.
 */

#import "DDesktopClientAppDelegate.h"


@interface DDesktopClientAppDelegate ()
- (void)showIndicatorViewWithMessage:(NSString*)message;
- (void)connectToHostInBackground:(NSNumber*)hostId;
@end


@implementation DDesktopClientAppDelegate


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{    
	{ // init setting
		_setting = [[Setting alloc] initWithFilePath:[NSString stringWithFormat:@"%@/Library/Preferences/setting.plist", NSHomeDirectory()]];
		
		SettingItem* itemImageQuality = [[[SettingItem alloc] initWithValue:[NSNumber numberWithInt:50]] autorelease];
		[itemImageQuality addMetaData:@"Image Quality" forKey:@"title"];
		[itemImageQuality addMetaData:[NSNumber numberWithDouble:1.0] forKey:@"min"];
		[itemImageQuality addMetaData:[NSNumber numberWithDouble:100.0] forKey:@"max"];
		[_setting setDefalutItem:itemImageQuality forKeyPath:@"Global.ImageQuality"];

		SettingItem* itemWheel = [[[SettingItem alloc] initWithValue:[NSNumber numberWithInt:2.0]] autorelease];
		[itemWheel addMetaData:@"Wheel Speed" forKey:@"title"];
		[itemWheel addMetaData:[NSNumber numberWithDouble:0.0] forKey:@"min"];
		[itemWheel addMetaData:[NSNumber numberWithDouble:4.0] forKey:@"max"];
		[_setting setDefalutItem:itemWheel forKeyPath:@"Global.WheelSpeed"];

		SettingItem* itemHostName = [[[SettingItem alloc] initWithValue:@"Host"] autorelease];
		[itemHostName addMetaData:@"Display Name" forKey:@"title"];
		[_setting setDefalutItem:itemHostName forKeyPath:@"HostTemplate.DisplayName"];

		SettingItem* itemHostAddress = [[[SettingItem alloc] initWithValue:@""] autorelease];
		[itemHostAddress addMetaData:@"IP Address" forKey:@"title"];
		[_setting setDefalutItem:itemHostAddress forKeyPath:@"HostTemplate.IPAddress"];

		SettingItem* itemHostPort = [[[SettingItem alloc] initWithValue:@"54321"] autorelease];
		[itemHostPort addMetaData:@"Port" forKey:@"title"];
		[_setting setDefalutItem:itemHostPort forKeyPath:@"HostTemplate.Port"];
		
		[_setting addDirectoryForKeyPath:@"HostList"];
	}
		
	_remoteViewContainerController = [[RemoteViewContainerController alloc] initWithAppStateManagerDelegate:self setting:_setting];
	_hostListViewController = [[HostListViewController alloc] initWithAppStateManagerDelegate:self setting:_setting];
	_hostInfoViewController = [[HostInfoViewController alloc] initWithAppStateManagerDelegate:self setting:_setting];
	_navigationController = [[UINavigationController alloc] initWithRootViewController:_hostListViewController];


	_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [_window addSubview:_navigationController.view];
    [_window makeKeyAndVisible];

	// call _remoteViewContainerCopntroller.laodView
	[_navigationController pushViewController:_remoteViewContainerController animated:NO];
	[_navigationController popViewControllerAnimated:NO];
	
	return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}


- (void)applicationWillTerminate:(UIApplication *)application {
	[_setting release];
	[_remoteViewContainerController stopSessionAndUnconnect];
}


#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}


- (void)dealloc {
    [_remoteViewContainerController release];
    [_window release];
    [super dealloc];
}


#pragma mark -
#pragma mark View Stack Handlers

-(void) popCurrentState
{
	_navigationController.navigationBarHidden = NO;
	[_navigationController popViewControllerAnimated:YES];
}


-(void) pushState:(enum APP_STATES)appState withParam:(int)param
{
	_navigationController.navigationBarHidden = NO;
	switch (appState) {
		case APP_STATE_SHOW_HOST_LIST:
			[_navigationController pushViewController:_remoteViewContainerController animated:YES];
			break;
		case APP_STATE_NEW_HOST_INFO:
			[_hostInfoViewController newHostInfo];
			[_navigationController pushViewController:_hostInfoViewController animated:YES];
			break;
		case APP_STATE_HOST_INFO_WITH_HOST_ID:
			[_hostInfoViewController loadHostInfoWithHostId:param];
			[_navigationController pushViewController:_hostInfoViewController animated:YES];
			break;
		case APP_STATE_CONNECT_TO_HOST_WITH_HOST_ID:
		{
			NSString* host = (NSString*)[_setting itemForKeyPath:[NSString stringWithFormat:@"HostList._item_[%d].IPAddress", param]].value;
			[self showIndicatorViewWithMessage:[NSString stringWithFormat:@"Connect to %@ ...", host]];
			[self performSelectorInBackground:@selector(connectToHostInBackground:) withObject:[NSNumber numberWithInt:param]];
		}
		default:
			break;
	}
}


-(void)showIndicatorViewWithMessage:(NSString*)message
{
	if(_indicatorView != nil){
		[_indicatorView release];
	}
	_indicatorView = [[UIView alloc] initWithFrame:[_navigationController topViewController].view.frame];
	
	UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
	spinner.center = _indicatorView.center;
	[spinner startAnimating];
	
	UILabel *messageLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,
																	  _indicatorView.frame.size.height * 0.6,
																	  _indicatorView.frame.size.width,
																	  30)];
	messageLabel.textAlignment = UITextAlignmentCenter;
	messageLabel.text = message;
	
	[_indicatorView addSubview:spinner];
	[_indicatorView addSubview:messageLabel];
	
	[_navigationController.view addSubview:_indicatorView];
	
	[messageLabel release];
	[spinner release];
	[_indicatorView release];
}


- (void)connectToHostInBackground:(NSNumber*)hostId
{
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

	NSString* host = (NSString*)[_setting itemForKeyPath:[NSString stringWithFormat:@"HostList._item_[%d].IPAddress", [hostId intValue]]].value;
	int port = [(NSNumber*)[_setting itemForKeyPath:[NSString stringWithFormat:@"HostList._item_[%d].Port", [hostId intValue]]].value intValue];

	if([_remoteViewContainerController connectToHost:host port:port]){
		[self performSelector:@selector(successToConnect:) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
	}
	else{
		[self performSelector:@selector(failedToConnect:) onThread:[NSThread mainThread] withObject:nil waitUntilDone:YES];
	}

	[_indicatorView removeFromSuperview];
	[_indicatorView release];
	_indicatorView = nil;

	[pool drain];
}


- (void)successToConnect:(NSObject*) obj
{
	if([_remoteViewContainerController startSession]){
		_navigationController.navigationBarHidden = YES;
		[_navigationController pushViewController:_remoteViewContainerController animated:YES];
	}
}

- (void)failedToConnect:(NSObject*) obj
{
}


@end
